package com.diorsunion.hedge.bo.quota;

import com.diorsunion.hedge.dal.entity.StockPrice;
import com.diorsunion.hedge.domain.MACD;
import com.diorsunion.hedge.domain.Trend;
import com.google.common.collect.Sets;

import java.util.List;
import java.util.Set;

/**
 * MCAD函数
 * Created by wanglaoshi on 2016/4/16.
 */
public class MACDFilter implements StockPriceFilter {


    @Override
    public void filter(List<StockPrice> stockPriceList) {
        mcad(stockPriceList);
    }

    /**
     * 弱金叉判断函数
     *
     * @param stockPriceList 判读金叉和死叉
     * @return
     */
    public static void mcad(List<StockPrice> stockPriceList) {
        if (stockPriceList == null || stockPriceList.size() < 2) {
            return;
        }
        for (int i = 1; i < stockPriceList.size(); i++) {
            StockPrice last = stockPriceList.get(i);
            Set<MACD> mcadResult = getMACD(stockPriceList, i);
            last.macds.addAll(mcadResult);
        }
        //自定义计算MACD
        for (int i = 0; i < stockPriceList.size(); i++) {
            StockPrice stockPrice = stockPriceList.get(i);
            double ema12,ema26,dif,dea,macd;
            Trend macdTrend = Trend.EVEN;
            if (i == 0) {
                ema12 = stockPrice.close;
                ema26 = stockPrice.close;
                dif = ema12 - ema26;
                dea = dif;
                macd = 0;
            } else {
                StockPrice stockPrice_yes = stockPriceList.get(i - 1);
                ema12 = stockPrice_yes.ex.ema12 * 11d / 13d + 2d / 13d * stockPrice.close;
                ema26 = stockPrice_yes.ex.ema26 * 25d / 27d + 2d / 27d * stockPrice.close;
                dif = ema12 - ema26;
                dea = stockPrice_yes.ex.dea * 0.8d + dif * 0.2d;
                macd = 1.6 * dif - 1.6 * stockPrice_yes.ex.dea;
                macdTrend = Trend.judge(stockPrice_yes.ex.macd,macd);
            }
            double price = calcPriceByMacd(ema12,ema26,dea,macd);
            stockPrice.ex.ema12 = ema12;
            stockPrice.ex.ema26 = ema26;
            stockPrice.ex.dif = dif;
            stockPrice.ex.dea = dea;
            stockPrice.ex.macd = macd;
            stockPrice.ex.price = price;
            stockPrice.ex.macdTrend = macdTrend;
        }
//        for (int i = 2; i < stockPriceList.size(); i++) {
//            StockPrice stockPrice = stockPriceList.get(i);
//            StockPrice s_2 = stockPriceList.get(i-2);
//            StockPrice s_1 = stockPriceList.get(i-1);
//            //如果要让MACD跟昨天一样的临界点的价格
//            double price = calcPriceByMacd(s_1.ex.ema12,s_1.ex.ema26,s_1.ex.dea,s_1.ex.macd);
//            stockPrice.ex.price = price;.
//
//        }
    }

    private static final Set<MACD> getMACD(List<StockPrice> stockPriceList, int i) {
        Set<MACD> set = Sets.newHashSet();
        if (stockPriceList == null || stockPriceList.size() < 2) {
            return set;
        }
        StockPrice last = stockPriceList.get(i);
        StockPrice last_pre = stockPriceList.get(i - 1);
        if (last_pre.dif < last_pre.dea && last.dif > last.dea && last.dif < 0 && last.dea < 0) {
            set.add(new MACD(MACD.Type.JINCHA, 4));
        }
        if (last_pre.dif < last_pre.dea && last.dif > last.dea && last.dif > 0 && last.dea > 0 && last.macd > 0) {
            set.add(new MACD(MACD.Type.JINCHA, 3));
        }
        if (last_pre.dif < last_pre.dea && last.dif > last.dea && last.dif > 0 && last.dea > 0) {
            set.add(new MACD(MACD.Type.JINCHA, 2));
        }
        if (last_pre.dif < last_pre.dea && last.dif > last.dea) {
            set.add(new MACD(MACD.Type.JINCHA, 1));
        }
        if (last_pre.dif > last_pre.dea && last.dif < last.dea && last.dif > 0 && last.dea > 0) {
            set.add(new MACD(MACD.Type.SICHA, 4));
        }
        if (last_pre.dif > last_pre.dea && last.dif < last.dea && last.dif < 0 && last.dea < 0 && last.macd < 0) {
            set.add(new MACD(MACD.Type.SICHA, 3));
        }
        if (last_pre.dif > last_pre.dea && last.dif < last.dea && last.dif < 0 && last.dea < 0) {
            set.add(new MACD(MACD.Type.SICHA, 2));
        }
        if (last_pre.dif > last_pre.dea && last.dif < last.dea) {
            set.add(new MACD(MACD.Type.SICHA, 1));
        }
        if (stockPriceList.size() > 2 && i > 1) {
            StockPrice last_pre_pre = stockPriceList.get(i - 2);
            if (last_pre_pre.macd < last_pre.macd && last_pre.macd > last.macd) {
                set.add(new MACD(MACD.Type.top_divergence, 1));
            }
            if (last_pre_pre.macd < last_pre.macd && last_pre.macd > last.macd && last.macd > 0) {
                set.add(new MACD(MACD.Type.top_divergence, 2));
            }
            if (last_pre_pre.macd > last_pre.macd && last_pre.macd < last.macd) {
                set.add(new MACD(MACD.Type.buttom_divergence, 1));
            }
            if (last_pre_pre.macd > last_pre.macd && last_pre.macd < last.macd && last.macd < 0) {
                set.add(new MACD(MACD.Type.buttom_divergence, 2));
            }

        }
        return set;
    }

    //利用MACD反推价格
    public static final double calcPriceByMacd(double s_ema12,double s_ema26,double s_dea,double macd){
        double price = (macd-1.6d*s_ema12*11d/13d+1.6d*s_ema26*25d/27d+1.6d*s_dea)/(1.6d * (2d/13d-2d/27d));
        return price;
    }


    //利用价格得到dif
    public static final double calcDifByPrice(double s_ema12,double s_ema26,double close){
        double ema12 = s_ema12 * 11d / 13d + 2d / 13d * close;
        double ema26 = s_ema26 * 25d / 27d + 2d / 27d * close;
        double dif = ema12 - ema26;
        return dif;
    }

    //利用价格得到dea
    public static final double calcDeaByPrice(double s_ema12,double s_ema26,double s_dea,double close){
        double dif = calcDifByPrice(s_ema12,s_ema26,close);
        double dea = s_dea * 0.8d + dif * 0.2d;
        return dea;
    }

    //利用价格得到MACD
    public static final double calcMacdByPrice(double s_ema12,double s_ema26,double s_dea,double close){
        double dif = calcDifByPrice(s_ema12,s_ema26,close);
        double dea = calcDeaByPrice(s_ema12,s_ema26,s_dea,close);
        double macd = (dif-dea)*2;
        return macd;
    }
}
